package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.dto.ClearCartItemRequest;
import com.cskaoyan.shopping.constants.ShoppingRetCode;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.form.CheckAllItemRequest;
import com.cskaoyan.shopping.service.ICartService;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: ZDongMing
 * @Date: 2022/8/25 13:40
 */
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    CartItemConverter cartItemConverter;

    @Autowired
    ItemMapper itemMapper;
    @Override

    public Collection<CartProductDto> getCartListById(Long userId) {
        String id = String.valueOf(userId);
        RMap<String, Map<String,CartProductDto>> map = redissonClient.getMap("cart");
        Map<String, CartProductDto> cartMap = map.get(id);
        if (cartMap==null){
            return new ArrayList<CartProductDto>();
        }
        Collection<CartProductDto> productDtos = cartMap.values();
        return productDtos;
    }

    @Override
    public void addToCart(CartRequest request) {
        String userId = String.valueOf(request.getUserId());
        Long productId = request.getProductId();
        RMap<String, Map<String,CartProductDto>> map = redissonClient.getMap("cart");
        Map cartMap = map.get(userId);
        Item item = itemMapper.selectByPrimaryKey(productId);
        if (cartMap!=null){
            CartProductDto cartProductDto = (CartProductDto) cartMap.get(String.valueOf(productId));
            if (cartProductDto!=null){
                cartProductDto.setProductNum(cartProductDto.getProductNum()+request.getProductNum());
                cartMap.put(String.valueOf(productId),cartProductDto);
                map.put(userId,cartMap);
                return;
            }
            cartProductDto = new CartProductDto();
            cartproducoDtoset(item,request,cartProductDto);
            cartMap.put(String.valueOf(productId),cartProductDto);
            map.put(userId,cartMap);
            return;
        }
        HashMap<String, CartProductDto> hashMap = new HashMap<>();
        CartProductDto cartProductDto = new CartProductDto();
        cartproducoDtoset(item,request,cartProductDto);
        hashMap.put(String.valueOf(productId),cartProductDto);
        map.put(userId,hashMap);
    }

    @Override
    public void updateCartNum(CartRequest request) {
        String userId = String.valueOf(request.getUserId());
        String productId = String.valueOf(request.getProductId());
        RMap<String, Map<String,CartProductDto>> map = redissonClient.getMap("cart");
        Map<String, CartProductDto> cartMap = map.get(userId);
        CartProductDto cartProductDto = cartMap.get(productId);
        if (request.getProductNum()>cartProductDto.getLimitNum()){
            //抛异常
            throw new BizException(ShoppingRetCode.CART_LIMIT.getCode(),ShoppingRetCode.CART_LIMIT.getMessage());
        }
        cartProductDto.setProductNum((long)(request.getProductNum()));
        cartProductDto.setChecked(request.getChecked());
        cartMap.put(productId,cartProductDto);
        map.put(userId,cartMap);
    }

    @Override
    public void checkAllCartItem(CheckAllItemRequest request) {
        RMap<String, Map<String, CartProductDto>> cart = redissonClient.getMap("cart");
        Map<String, CartProductDto> map = cart.get(request.getUserId().toString());
        if (map.size() == 0) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
                    ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }

        Set<String> strings = map.keySet();
        for (String s : strings) {
            CartProductDto dto = map.get(s);
            dto.setChecked(request.getChecked());
        }
        cart.put(request.getUserId().toString(), map);
    }

    @Override
    public void deleteCartItem(Long uid, Long itemId) {
        RMap<String, Map<String, CartProductDto>> cart = redissonClient.getMap("cart");
        Map<String, CartProductDto> map = cart.get(uid.toString());
        if (map.size() == 0) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
                    ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }

        CartProductDto remove = map.remove(itemId.toString());

        // if (remove == null) {
        //     throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
        //             ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        // }
        cart.put(uid.toString(), map);
    }

    @Override
    public void deleteCheckedItem(Long userId) {
        RMap<String, Map<String, CartProductDto>> cart = redissonClient.getMap("cart");
        Map<String, CartProductDto> map = cart.get(String.valueOf(userId));
        if (map.size() == 0) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
                    ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }

        ArrayList<String> list = new ArrayList<>();

        Set<String> strings = map.keySet();

        for (String s : strings) {
            CartProductDto dto = map.get(s);
            if ("true".equals(dto.getChecked())) {
                list.add(s);
            }
        }

        strings.removeAll(list);

        cart.put(String.valueOf(userId), map);
    }

    @Override
    public void clearCartItemByUserID(ClearCartItemRequest request) {
        @NotNull Long userId = request.getUserId();
        String id = String.valueOf(userId);
        RMap<String, Map<String,CartProductDto>> map = redissonClient.getMap("cart");
        Map<String, CartProductDto> cartMap = map.get(id);
        @NotEmpty List<Long> productIds = request.getProductIds();
        for (Long productId : productIds) {
            String idStr = String.valueOf(productId);
            cartMap.remove(idStr);
        }
        map.put(id,cartMap);


       // deleteCheckedItem(userId);

    }
    private void cartproducoDtoset(Item item,CartRequest request,CartProductDto cartProductDto){
        cartProductDto.setChecked(request.getChecked());
        cartProductDto.setProductId(request.getProductId());
        cartProductDto.setProductNum((long)(request.getProductNum()));
        cartProductDto.setProductImg(item.getImages()[0]);
        cartProductDto.setProductName(item.getTitle());
        cartProductDto.setLimitNum((long)(item.getLimit_num()));
        cartProductDto.setSalePrice(item.getPrice());
        cartProductDto.setChecked("true");
    }
}
